Flush kernel's TCP buffer with `MSG_MORE`-flagged packets
Posted
by timn
on Stack Overflow
See other posts from Stack Overflow
or by timn
Published on 2010-03-30T19:11:45Z
Indexed on
2010/03/30
19:13 UTC
Read the original article
Hit count: 490
send()'s man page reveals the MSG_MORE
flag which is asserted to act like TCP_CORK
. I have a wrapper function around send()
:
int SocketConnection_Write(SocketConnection *this, void *buf, int len) {
errno = 0;
int sent = send(this->fd, buf, len, MSG_NOSIGNAL);
if (errno == EPIPE || errno == ENOTCONN) {
throw(exc, &SocketConnection_NotConnectedException);
} else if (errno == ECONNRESET) {
throw(exc, &SocketConnection_ConnectionResetException);
} else if (sent != len) {
throw(exc, &SocketConnection_LengthMismatchException);
}
return sent;
}
Assuming I want to use the kernel buffer, I could go with TCP_CORK
, enable whenever it is necessary and then disable it to flush the buffer. But on the other hand, thereby the need for an additional system call arises. Thus, the usage of MSG_MORE
seems more appropriate to me. I'd simply change the above send() line to:
int sent = send(this->fd, buf, len, MSG_NOSIGNAL | MSG_MORE);
According to lwm.net, packets will be flushed automatically if they are large enough:
If an application sets that option on a socket, the kernel will not send out short packets. Instead, it will wait until enough data has shown up to fill a maximum-size packet, then send it. When TCP_CORK is turned off, any remaining data will go out on the wire.
But this section only refers to TCP_CORK
. Now, what is the proper way to flush MSG_MORE
packets?
I can only think of two possibilities:
- Call send() with an empty buffer and without
MSG_MORE
being set - Re-apply the TCP_CORK option as described on this page
Unfortunately the whole topic is very poorly documented and I couldn't find much on the Internet.
I am also wondering how to check that everything works as expected? Obviously running the server through strace' is not an option. So the only simplest way would be to use
netcat' and then look at its `strace' output? Or will the kernel handle traffic differently transmitted over a loopback interface?
© Stack Overflow or respective owner